﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ignitron.EEngine.Maths;
using Ignitron.EEngine.Lighting;
using Ignitron.EEngine.Model;
using System.Windows;

namespace Ignitron.EEngine
{
    /// <summary>
    /// Engine mouse event arguments
    /// </summary>
    public class EMouseEventArgs: EventArgs
    {
        /// <summary>
        /// The mouse position
        /// </summary>
        public Point Position;

        /// <summary>
        /// Mouse wheel delta
        /// </summary>
        public int WheelDelta;
    }

    /// <summary>
    /// Represents an interface for the class providing background of the engine's rendered view
    /// </summary>
    public interface IBackground
    {
        /// <summary>
        /// Width of image
        /// </summary>
        int Width
        { get; }

        /// <summary>
        /// Height of image
        /// </summary>
        int Height
        { get; }

        /// <summary>
        /// The data itself
        /// </summary>
        byte[,,] Pixels
        { get; }
    }

    /// <summary>
    /// Engine interface
    /// </summary>
    public interface IEngine
    {
        DependencyObject Control
        { get; }

        /// <summary>
        /// True flag, when the initialization process of the engine is completed
        /// </summary>
        bool IsInitializationCompleted
        { get; }

        /// <summary>
        /// Closes and shuts down the engine
        /// </summary>
        void Close();

        /// <summary>
        /// Camera settings
        /// </summary>
        void SetCamera(EVector3 position, EVector3 lookAt, EVector3 up);
        void SetFOV(float fov);
        void SetNearFarLimits(float near, float far);


        /// <summary>
        /// Rendering request event
        /// </summary>
        event EventHandler RenderRequestEvent;

        /// <summary>
        /// Mouse handling events
        /// </summary>
        event EventHandler<EMouseEventArgs> LeftButtonDownEvent;
        event EventHandler<EMouseEventArgs> LeftButtonUpEvent;
        event EventHandler<EMouseEventArgs> RightButtonDownEvent;
        event EventHandler<EMouseEventArgs> RightButtonUpEvent;
        event EventHandler<EMouseEventArgs> MouseMoveEvent;
        event EventHandler<EMouseEventArgs> MouseWheelEvent;

        Size GetViewportSize();
        EMatrix4 GetWorldMatrix();
        EMatrix4 GetViewMatrix();
        EMatrix4 GetProjectionMatrix();

        void SetCapture();
        void ReleaseCapture();

        /// <summary>
        /// Rendering methods
        /// </summary>
        void InvokeRendering();
        void BeginRender();
        void EndRender();
        void BeginPoints();
        void EndPoints();
        void BeginLines();
        void EndLines();

        /// <summary>
        /// Rendering methods
        /// </summary>
        void RenderPoint(EVector3 p0, EVector4 color);
        void RenderLine(EVector3 p1, EVector3 p2, EVector4 color);
        void RenderModel(EModel model);
        void RenderNormals(EModel model, float magnitude, EVector4 color);

        /// <summary>
        /// Factory methods
        /// </summary>
        EModel CreateModel();
        ETexture CreateTexture();

        /// <summary>
        /// Rendering matrix calculations stack
        /// </summary>
        void PushMatrix();
        void MultMatrix(ref EMatrix4 matrix);
        void LoadIdentity();
        void PopMatrix();

        /// <summary>
        /// Setting methods
        /// </summary>        
        void SetAlphaBlend(float alpha);
        void SetMaterial(EMaterial material);
        void SetTexture(ETexture texture);
        void SetClearColor(EVector4 color);
        void SetBackground(IBackground background);

        /// <summary>
        /// Lighting
        /// </summary>
        void EnableLighting(bool enabled);
        ELight CreateLight();
        void RenderLight(ELight light);
        void SetGlobalAmbient(EVector3 color);

        /// <summary>
        /// Rendering to texture methods
        /// </summary>
        void InitializeRenderingTexture(int width, int height);
        void BeginRenderToTexture();
        void DrawTexture(ETexture texture, int x, int y, int width, int height);
        void DrawRect(int x, int y, int width, int height, EVector4 color);
        ETexture EndRenderToTexture();
    }

    internal interface IEngineExtended : IEngine
    {
        IRenderingControl RenderingControl
        { get; }
    }

    /// <summary>
    /// Interface for rendering controls of various platforms
    /// </summary>
    internal interface IRenderingControl
    {
        void Resize(Size size);
    }
}
